package cc.jq1024.domain.strategy.repository;

import cc.jq1024.domain.strategy.model.entity.StrategyAwardEntity;
import cc.jq1024.domain.strategy.model.entity.StrategyEntity;
import cc.jq1024.domain.strategy.model.entity.StrategyRuleEntity;
import cc.jq1024.domain.strategy.model.valobj.RuleTreeVO;
import cc.jq1024.domain.strategy.model.valobj.RuleWeightVO;
import cc.jq1024.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import cc.jq1024.domain.strategy.model.valobj.StrategyAwardStockKeyVO;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: jia-qiang ljq1024.cc
 * @desc: 策略仓储接口
 * @Date: 2024-04-11-22:23
 */
public interface IStrategyRepository {

    /**
     * 查询指定抽奖策略下的奖策奖品集合
     */
    List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);

    /**
     * 存储策略奖品概率查找表到redis中
     */
    void storeStrategyAwardSearchRateTable(String key, int rateRangeSize, HashMap<Integer, Long> shuffleStrategyAwardSearchRateTable);

    /**
     * 获取存储抽奖策略范围值 -> 没有权重装配的情况
     */
    Integer getRateRange(Long strategyId);

    /**
     * 获取存储抽奖策略范围值 -> 权重装配的情况
     */
    Integer getRateRange(String key);

    /**
     * 获取随机奖品ID -> 没有权重装配的情况
     */
    Long getStrategyAwardAssemble(Long strategyId, int randomRate);

    /**
     * 获取随机奖品ID -> 权重装配的情况
     */
    Long getStrategyAwardAssemble(String key, int randomRate);

    /**
     * 通过策略ID查询策略实体
     */
    StrategyEntity queryStrategyEntityByStrategyId(Long strategyId);

    /**
     * 查询指定策略ID和抽奖规则类型的策略规则实体
     */
    StrategyRuleEntity queryStrategyRuleEntity(Long strategyId, String ruleModel);

    /**
     * 根据策略ID,奖品ID(可能是null),规则模型查询 规则模型信息
     */
    String queryStrategyRuleValue(Long strategyId, Long awardId, String ruleModel);

    /**
     * 重载方法： 根据策略ID,奖品ID(可能是null -> 不传),规则模型查询 规则模型信息
     */
    String queryStrategyRuleValue(Long strategyId, String ruleModel);

    /**
     * 查询策略奖品配置的规则模型
     */
    StrategyAwardRuleModelVO queryStrategyAwardRuleModelVO(Long strategyId, Long awardId);

    /**
     * 根据规则树ID，查询树结构信息
     *
     * @param treeId 规则树ID
     * @return 树结构信息
     */
    RuleTreeVO queryRuleTreeVOByTreeId(String treeId);

    /**
     * 缓存产品库存
     *
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     * @param awardCount 库存量
     */
    void cacheStrategyAwardCount(Long strategyId, Long awardId, Integer awardCount);

    /**
     * 扣减奖品缓存库存
     */
    Boolean subtractionAwardStock(Long strategyId, Long awardId);

    /**
     * 扣减奖品缓存库存 - 带有结束时间
     */
    Boolean subtractionAwardStock(Long strategyId, Long awardId, Date endDateTime);

    /**
     * 写入延迟队列，延迟消费更新数据库记录
     */
    void awardStockConsumeSendQueue(StrategyAwardStockKeyVO strategyAwardStockKeyVO);

    /**
     * 获取奖品库存消耗队列
     */
    StrategyAwardStockKeyVO takeQueueValue();

    /**
     * 更新奖品库存消耗记录
     */
    void updateStrategyAwardStock(Long strategyId, Long awardId);

    /**
     * 根据策略ID+奖品ID的唯一值组合，查询奖品信息
     *
     * @param strategyId 策略ID
     * @param awardId    奖品ID
     * @return 奖品信息
     */
    StrategyAwardEntity queryStrategyAwardEntity(Long strategyId, Long awardId);

    /**
     * 清空队列
     */
    void clearQueueValue();

    /**
     * 清空数据库库存
     */
    void clearStrategyAwardStock(Long strategyId, Long awardId);

    /**
     * 通过活动ID查询策略ID
     */
    Long queryStrategyIdByActivityId(Long activityId);

    /**
     * 查询用户抽奖次数 - 当天的；策略ID:活动ID 1:1 的配置，可以直接用 strategyId 查询。
     */
    Integer queryTodayUserRaffleCount(String userId, Long strategyId);

    /**
     * 根据规则树ID集合查询奖品中加锁数量的配置「部分奖品需要抽奖N次解锁」
     *
     * @param treeIds 规则树ID值
     * @return key 规则树，value rule_lock 加锁值
     */
    Map<String, Integer> queryAwardRuleLockCount(String... treeIds);

    /**
     * 查询用户参与总次数
     *
     * @param userId     用户ID
     * @param strategyId 策略ID
     * @return 用户参与总次数
     */
    Integer queryActivityAccountTotalUseCount(String userId, Long strategyId);

    /**
     * 查询奖品权重配置
     *
     * @param strategyId 策略ID
     * @return 权重规则
     */
    List<RuleWeightVO> queryAwardRuleWeight(Long strategyId);
}
